package com.basker.pisces.core.query.meta;

import java.text.MessageFormat;
import java.util.Objects;

import org.springframework.util.StringUtils;

import com.basker.pisces.core.meta.IField;
import com.basker.pisces.core.meta.row.RowDataField;
import com.basker.pisces.core.query.GroupField;
import com.basker.pisces.core.query.OrderField;
import com.basker.pisces.core.query.QueryInfo;
import com.basker.pisces.core.query.SelectField;
import com.basker.pisces.resource.StringResources;

public class FieldDesc {

    /**
     * 关联表字段外部传入都是通过"."分割的，但是无论数据库别名还是前端js对象，对.的处理都不友好，故这里统一分隔符为"_"
     *
     * @param input
     * @return
     */
    public static String resolveSplit(String input) {
        if (StringUtils.isEmpty(input)) {
            return input;
        }

        if (input.contains(".")) {
            return input.replace('.', '_');
        }

        return input;
    }

    private String id;
    private String name;
    private String alias;
    private String displayName;

    private transient Class<?> valueType;
    private transient TableDesc hostTable;

    public FieldDesc() {

    }

    public FieldDesc(String id, String name, String alias, String displayName, Class<?> valueType) {
        this.id = this.resolve(id);
        this.name = name;
        this.alias = this.resolve(alias);
        this.displayName = displayName;
        this.valueType = valueType;
    }

    public IField createField(QueryInfo queryInfo) {
        RowDataField rowDataField = new RowDataField(this);

        if (queryInfo.isSelectMode() && this.getHostTable().isReferenceTable()) {
            TableDesc refTable = this.getHostTable();
            rowDataField.setHostTableFkFieldName(refTable.getFkField().getAlias());
        }

        return rowDataField;
    }

    public String getAlias() {
        return alias;
    }

    public String getDisplayName() {
        return !StringUtils.isEmpty(displayName) ? StringResources.resolve(displayName) : "";
    }

    /**
     * 拼接SQL语句过程中，获取字段分组的表达式
     *
     * @param groupField
     * @return
     */
    public String getGroupFieldName(GroupField groupField) {
        return this.getHostTable().getFullFieldName(this.getName());
    }

    public TableDesc getHostTable() {
        return hostTable;
    }

    public String getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    /**
     * 拼接SQL语句过程中，获取字段排序的表达式
     *
     * @param orderField
     * @return
     */
    public String getOrderFieldName(OrderField orderField) {
        String fieldFullName = this.getHostTable().getFullFieldName(this.getName());
        String order = orderField.getOrder() != null ? orderField.getOrder() : "";

        return MessageFormat.format("{0} {1}", fieldFullName, order);
    }

    /**
     * 拼接SQL语句过程中，获取字段查询的表达式
     *
     * @param orderField
     * @return
     */
    public String getSelectFieldName(SelectField selectField) {
        String selectExp = selectField.genSelectExpression(this);
        String alias = this.genSelectAlias(selectField);

        return MessageFormat.format("{0} AS {1}", selectExp, alias);
    }

    public Class<?> getValueType() {
        return valueType;
    }

    public void setAlias(String alias) {
        this.alias = this.resolve(alias);
    }

    public void setDisplayName(String displayName) {
        this.displayName = displayName;
    }

    public void setHostTable(TableDesc hostTable) {
        this.hostTable = hostTable;
    }

    public void setId(String id) {
        this.id = this.resolve(id);
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setValueType(Class<?> valueType) {
        this.valueType = valueType;
    }

    @Override
    public String toString() {
        String ret = null;

        if (Objects.equals(this.id, this.alias)) {
            ret = this.id;
        } else {
            ret = MessageFormat.format("id:{0},alias:{0}", this.id, this.alias);
        }

        return ret;
    }

    /**
     * 获取查询字段的别名，别名与契约属性一致
     *
     * @param selectField
     * @return
     */
    protected String genSelectAlias(SelectField selectField) {
        String alias = this.resolve(selectField.getAlias());
        if (StringUtils.isEmpty(alias)) {
            alias = this.alias;
        }

        return alias;
    }

    private String resolve(String input) {
        return resolveSplit(input);
    }

}
